----------------------------------------------------------------
-- Global Variables
----------------------------------------------------------------

BankWindow = {}
BankWindow.items = {}

BankWindow.versionNumber = 0.01

BankWindow.DEBUG_ON = false
BankWindow.DEBUG_LEVEL = 5


BankWindow.NUM_BANK_SLOTS = 80
BankWindow.NUM_COLS = 8
BankWindow.NUM_ROWS = 10

BankWindow.windowName = "BankWindow"
BankWindow.dropPending = false

----------------------------------------------------------------
-- Local Variables
----------------------------------------------------------------


----------------------------------------------------------------
-- Local Functions

local function SendDebug( text, level )
	if level and level < BankWindow.DEBUG_LEVEL then
		return
	end

    if BankWindow.DEBUG_ON then
        DEBUG( text )
    end
end

-- End Local Functions
----------------------------------------------------------------



----------------------------------------------------------------
-- BankWindow Functions

-- OnInitialize Handler
function BankWindow.Initialize()    
    SendDebug(L"BankWindow.Initialize")
    
    WindowRegisterEventHandler( BankWindow.windowName, SystemData.Events.INTERACT_OPEN_BANK, "BankWindow.OpenBank")
    WindowRegisterEventHandler( BankWindow.windowName, SystemData.Events.PLAYER_BANK_SLOT_UPDATED, "BankWindow.UpdateBankSlots")
    WindowRegisterEventHandler( BankWindow.windowName, SystemData.Events.INTERACT_DONE, "BankWindow.Hide")
    
    LabelSetText( BankWindow.windowName.."TitleBarText", GetString( StringTables.Default.LABEL_PLAYER_VAULT_TITLE ) )
	
	BankWindow.InitializeSlots()
end


-- OnShutdown Handler
function BankWindow.Shutdown()

	BankWindow.Hide()
end

function BankWindow.OnRButtonDown()

    EA_Window_ContextMenu.CreateDefaultContextMenu( BankWindow.windowName )
end

-- Show the Bank
function BankWindow.Show()
	WindowSetShowing( BankWindow.windowName, true )
end

function BankWindow.OnShown()

    WindowUtils.OnShown(BankWindow.Hide, WindowUtils.Cascade.MODE_AUTOMATIC)
    EA_BackpackUtilsMediator.ShowBackpack()
end


-- Hide the Bank
function BankWindow.Hide()

	WindowSetShowing( BankWindow.windowName, false )
end

function BankWindow.OnHidden()

    WindowUtils.OnHidden()
end


function BankWindow.ToggleShowing()
    WindowUtils.ToggleShowing( BankWindow.windowName )
end


function BankWindow.IsShowing()
    return WindowGetShowing( BankWindow.windowName )
end


-- Show the Bank
function BankWindow.OpenBank()

	-- TODO: this should be controlled by DataUtils so we can use dirty flags same as other item groups
	local bankItems = DataUtils.GetBankData()		
	BankWindow.UpdateAllBankSlots( bankItems )
	BankWindow.Show()
end


function BankWindow.InitializeSlots()
    SendDebug( L"InitializeSlots")

	for slot = 1, BankWindow.NUM_BANK_SLOTS do
		BankWindow.SetBankSlot( slot, nil )
	end
end

function BankWindow.GetSlotWindowForSlotNumber( slotNumber )  
SendDebug( L"BankWindow.GetSlotWindowForSlotNumber slotNumber = "..slotNumber, 4 )

    local row = math.ceil(slotNumber / BankWindow.NUM_COLS)
    local col = slotNumber - ((row-1) * BankWindow.NUM_COLS)
    
SendDebug( L"  returning BankWindowSlotsRow"..row..L"Col"..col, 2 )
	return "BankWindowSlotsRow"..row.."Col"..col
end

-- ASSUMPTION: only pass in valid bank slot window names
function BankWindow.GetSlotNumberForSlotWindow( slotWindowName )  
SendDebug( L"BankWindow.GetSlotNumberForSlotWindow  slotWindowName = "..StringToWString(slotWindowName), 3 )

    local col = WindowGetId( slotWindowName )
    local row = WindowGetId( WindowGetParent( slotWindowName ) )
    
SendDebug( L"  returning  slotNumber = "..col + (row-1)* BankWindow.NUM_COLS, 2 )
    return col + (row-1)* BankWindow.NUM_COLS
end

function BankWindow.GetSlotNumberForCurrentWindow()  

	local slotWindowName = SystemData.ActiveWindow.name
	return BankWindow.GetSlotNumberForSlotWindow( slotWindowName ) 
end



function BankWindow.UpdateAllBankSlots( updatedSlots )
    SendDebug( L"UpdateAllBankSlots")
    
	local itemData
    if updatedSlots ~= nil then
    
		BankWindow.items = updatedSlots
         
		for slot = 1, BankWindow.NUM_BANK_SLOTS do
		
			itemData = BankWindow.items[slot]
			BankWindow.SetBankSlot( slot, itemData ) 
		end
    end
end


-- SystemData.Events.PLAYER_BANK_SLOT_UPDATED Handler
function BankWindow.UpdateBankSlots( updatedSlots )

	-- NOTE: since we don't have a working UPDATE_ALL call, wait until we open up
	--       the bank window and fetch all 80 items at one time
    if BankWindow.IsShowing() == false then
        return  
    end 
    
    -- BankWindow.UpdateBankSlot() will grab itemData from C++ one slot at a time
    -- If for any reason we send more than 2 slots at a time, then we're likely 
    -- clearing or setting all 80 slots so just use UpdateAllBankSlots() to 
    -- grab them all and update them all at one time. 
    --
    if #updatedSlots > 2 then
		BankWindow.UpdateAllBankSlots( updatedSlots )
	else
		for _, slot in ipairs( updatedSlots ) do
			BankWindow.UpdateBankSlot( slot )
		end
	end
end

-- SystemData.Events.PLAYER_BANK_SLOT_UPDATED Handler
function BankWindow.UpdateBankSlot( slot )
	SendDebug( L"BankWindow.UpdateBankSlot  slot="..slot, 6 )
    
    -- make sure slot number is in proper range
    if slot < 1 or slot > BankWindow.NUM_BANK_SLOTS then
		 DEBUG(L"ERROR in BankWindow.UpdateBankSlot received out of range slot index = "..slot)
        return  
    end 
    
    local itemData  = GetSingleItem( GameData.ItemLocs.BANK, slot, false )
    
    BankWindow.items[slot] = itemData
    BankWindow.SetBankSlot( slot, itemData )

    -- If we are placing the item that is currently on the cursor, clear it
    if( Cursor.IconOnCursor() and itemData and (Cursor.Data.ObjectId == itemData.uniqueID or BankWindow.dropPending == true) ) then 
        Cursor.Clear()
    end
    
    -- If we are mousing over the updated slot, show the tooltip
    local slotName = BankWindow.GetSlotWindowForSlotNumber( slot )
    if( SystemData.MouseOverWindow.name == slotName ) then    
        BankWindow.EquipmentMouseOver( slot )
    end
    
end



function BankWindow.SetBankSlot( slot, itemData )
	SendDebug(L"SetBankSlot slot="..slot, 4 )
	
	local buttonName = BankWindow.GetSlotWindowForSlotNumber( slot ) 
	if DoesWindowExist( buttonName ) == false then
		ERROR(L"BankWindow.SetBankSlot failed to find window="..StringToWString(buttonName) )
		return
	end
	
    -- Clear the Slot if no item is set.
    if not DataUtils.IsValidItem( itemData ) then
               
        DynamicImageSetTexture (buttonName.."Icon", "", 0, 0)
		WindowSetShowing( buttonName.."Text", false )
        WindowSetGameActionData( buttonName, 0, 0, L"")
        
		WindowSetShowing( buttonName.."Cooldown", false )
		WindowSetShowing( buttonName.."CooldownTimer", false )
        return
    end

    -- Icon
    local texture, x, y = GetIconData(itemData.iconNum)
    DynamicImageSetTexture( buttonName.."Icon", texture, x, y)
    
    -- Count            
    WindowSetShowing( buttonName.."Text", itemData.stackCount > 1 )
    if itemData.stackCount > 1 then
        --ButtonSetText(buttonName, L""..itemData.stackCount )
        LabelSetText(buttonName.."Text", L""..itemData.stackCount )
    end
    
end

--
function BankWindow.GetItem(slot)
    
    if (slot == nil or slot <= 0 or slot > BankWindow.NUM_BANK_SLOTS) then
        return nil
    end
    
    return BankWindow.items[slot]
end


---------------------------------
--- Item Handlers -----
---------------------------------

-- OnLButtonDown Handler
function BankWindow.EquipmentLButtonDown( flags )

	local slot = BankWindow.GetSlotNumberForCurrentWindow()  
	SendDebug(L"EquipmentLButtonDown slot="..slot, 7 )
    local itemData = BankWindow.GetItem(slot)

    if Cursor.IconOnCursor() then
        
        -- don't bother sending a move item if we're dropping on the original slot. just clear the cursor
        --   Same for list mode
        if( Cursor.Data.Source == Cursor.SOURCE_BANK and Cursor.Data.SourceSlot == slot ) then 
			
            Cursor.Clear()        
           
        else  
            RequestMoveItem( Cursor.Data.Source, Cursor.Data.SourceSlot, Cursor.SOURCE_BANK, slot, Cursor.Data.StackAmount )            
            BankWindow.dropPending = true
        end
        
    else
        if DataUtils.IsValidItem( itemData ) then
            if flags == SystemData.ButtonFlags.SHIFT  then
                -- This doesn't send the item data for some reason
                --EA_ChatWindow.InsertItemLink( itemData )
            else
                Cursor.PickUp( Cursor.SOURCE_BANK, slot, itemData.uniqueID, itemData.iconNum, true)
            end
        end
        BankWindow.dropPending = false
    end
        
end

-- OnLButtonUp Handler
function BankWindow.EquipmentLButtonUp()
	SendDebug(L"EquipmentLButtonUp", 5 )

	local slot = BankWindow.GetSlotNumberForCurrentWindow()  
	
    if Cursor.IconOnCursor() and BankWindow.dropPending == false then
    
        -- Attempt to drop the object
        RequestMoveItem( Cursor.Data.Source, Cursor.Data.SourceSlot, Cursor.SOURCE_BANK, slot, Cursor.Data.StackAmount )
    end
end


-- OnRButtonDown Handler
function BankWindow.EquipmentRButtonDown( flags )
	SendDebug(L"EquipmentLButtonUp", 5 )

	local slot = BankWindow.GetSlotNumberForCurrentWindow()  
	local itemData = BankWindow.GetItem( slot )
    
    -- verify that we're clicking on an icon before spamming the server
    if not Cursor.IconOnCursor() and DataUtils.IsValidItem( itemData ) then

		
		if( (flags == SystemData.ButtonFlags.SHIFT) and itemData.stackCount > 1 ) then
			-- If Shift is Pressed, Show the stack count window
			ItemStackingWindow.Show(Cursor.SOURCE_BANK, slot)
		else
			 -- Attempt to put this item back into the inventory
			RequestMoveItem( Cursor.SOURCE_BANK, slot, Cursor.SOURCE_INVENTORY, GameData.Inventory.FIRST_AVAILABLE_INVENTORY_SLOT, itemData.stackCount)
		end

    end
end


function BankWindow.EquipmentMouseOver()
	SendDebug( L"EquipmentMouseOver", 3 )

	local slot = BankWindow.GetSlotNumberForCurrentWindow()  
    local itemData = BankWindow.GetItem( slot )
                
    if not DataUtils.IsValidItem( itemData ) then
    
        Tooltips.ClearTooltip()   
    else 
    
        local anchorWindow = SystemData.ActiveWindow.name
        Tooltips.CreateItemTooltip( itemData, 
                                    anchorWindow,
                                    Tooltips.ANCHOR_WINDOW_RIGHT, 
                                    Tooltips.ENABLE_COMPARISON )
    end
    
end
